import { fabric } from 'fabric'
import { Canvas } from 'fabric/fabric-impl'
import { BasicItemOption, ItemStyle, hasParentType, ItemTextStyle } from './types/global'
import { EventEmitter } from './EventEmitter'
//import { DaoDaoMindMap } from './DaodaoMindMap'

export class BasicItem extends EventEmitter{
	canvas: Canvas
	iText: hasParentType<fabric.Textbox>
	rect: hasParentType<fabric.Rect>
	resizeBtn: hasParentType<fabric.Rect>
	hasChangeWidth: boolean
	option: BasicItemOption
	padding: number
	autoMinWidth: number
	type: string
	resizeflag: boolean
	staticStyle: ItemStyle
	constructor(canvas: Canvas, option: BasicItemOption = {}) {
		super()
		this.canvas = canvas
		this.hasChangeWidth = false
		this.option = option
		this.padding = 10
		this.rect = this.initRect()
		this.iText = this.initiText()
		this.resizeBtn = this.initResizeBtn()
		this.autoMinWidth = 280
		this.type = 'childItem'
		this.staticStyle = {}
		this.resizeflag = false
		this.init()
	}
	init() {
		//isEditing 指示文本是否处于编辑模式
		//linethrough 文本装饰线条。
		//overline 文本装饰线条。
		//underline
		//selectionEnd
		//selectionStart
		//textAlign
		//textBackgroundColor
		//_measureLine(lineIndex)
		// _splitTextIntoLines(text) → {Array} Returns the text as an array of lines.
		//enterEditing()
		//exitEditing() 
		//get2DCursorLocation(selectionStartopt, skipWrappingopt)
		//getCurrentCharColor() → {String|fabric.Gradient|fabric.Pattern}
		//getSelectedText()
		//isOnScreen(calculateopt)
		// this.redrawBox()
		// this.canvas.requestRenderAll()
	}
	initiText() {
		this.iText = new fabric.Textbox(this.option.text || '新节点', {
			fontSize: 18,
			lineHeight: 1.2,
			textAlign: 'left', // 文字对齐
			lockRotation: true, // 禁止旋转
			lockScalingY: true, // 禁止Y轴伸缩
			lockScalingFlip: true, // 禁止负值反转
			splitByGrapheme: false, // 拆分中文，可以实现自动换行
			left:this.option?.left || 0,
			top:this.option?.top || 0,
			borderColor: 'transparent', // 控制器边框颜色
			cornerColor: 'transparent',  // 控制器几个控制柄的颜色
			cornerSize: 12, // 控制器控制柄大小，
			opacity: 1,
			selectable:true, //是否可被选择
			visible: true,
			backgroundColor: 'transparent',
			cursorColor:'#0e0e0e',//光标颜色
			editable:true,
			editingBorderColor:'transparent',
			padding: this.padding,
			objectCaching: false,
		})

		this.canvas.add(this.iText)

		this.iText.setControlsVisibility({
			'mtr':false,
			'bl':false,
			'br':false,
			'mb':false,
			'tl':false,
			'tr':false,
			'mt':false,
			'ml':false,
			'mr':false
		})
		this.iText.on('moving',() => {
			this.redrawBox()
		})
		this.iText.on('editing:entered',() => {
			console.log('entered')
		})
		this.iText.on('editing:exited',() => {
			console.log('exited')
		})
		this.iText.on('changed',() => {
			this._countTextWidth()
			setTimeout(() => {
				this.redrawBox()
			},10)
		})
		//this.iText!.get2DCursorLocation() 返回光标位置
		//getSelectionStyles(startIndexopt, endIndexopt, completeopt) → {Array} 返回选中部分的样式
		//setSelectionStyles(stylesopt, startIndexopt, endIndexopt) → {fabric.IText}
		this.iText.on('selection:changed', () => {
			// console.log('selection:changed',this.iText!.get2DCursorLocation(),this.iText?.selectionStart, this.iText?.selectionEnd)
			// this.iText?.setSelectionStyles({
			// 	textBackgroundColor:'green'
			// })
			// const style = this.iText!.getSelectionStyles(this.iText?.selectionStart, this.iText?.selectionEnd, false)
			// console.log(style)
		})
		this.iText.on('resizing',() => {
			if(!this.hasChangeWidth && this.iText) {
				this.hasChangeWidth = true
				this.iText.splitByGrapheme = true
			}
			this.redrawBox()
		})

		return this.iText
	}
	initRect() {
		// 创建rect
		this.rect = new fabric.Rect({
			selectable: false,
			evented: true,
			fill : '#5DBADC', //填充的颜色
			rx: 4, //圆角半径
			ry: 4, //圆角半径
			strokeWidth: 2,
			objectCaching: false,
			left: (this.option.left || 0) - this.padding,
			top: (this.option.top || 0) - this.padding,
		})
		this.canvas.add(this.rect)
		return this.rect
	}
	initResizeBtn() {
		this.resizeBtn = new fabric.Rect({
			fill : 'transparent', //填充的颜色
			objectCaching: false,
			left: 0,
			top: 0,
			width: 10,
			height: 0,
			hasControls: false,
			lockMovementX: true,
			lockMovementY: true,
			hoverCursor: 'e-resize',
			borderColor: 'transparent', // 控制器边框颜色
		})
		this.resizeBtn.on('mousedown',() => {
			this.resizeflag = true
		})
		this.resizeBtn.on('mousemove',(e) => {
			if(this.resizeflag) {
				console.log('basic move ', e)
				const x = e.absolutePointer?.x || 0
				const width = x - (this.iText?.left || 0) - this.padding
				this.iText.set({
					width: width
				})
				if(!this.hasChangeWidth && this.iText) {
					this.hasChangeWidth = true
					this.iText.splitByGrapheme = true
				}
				this.redrawBox()
			}
		})
		this.resizeBtn.on('mouseup',() => {
			this.resizeflag = false
		})
		this.canvas.add(this.resizeBtn)
		return this.resizeBtn
	}
	redrawBox() {
		if(this.iText && this.rect) {
			const zoom = this.canvas.getZoom()
			this.iText.padding = this.padding*zoom
			this.rect.set({
				left: (this.iText.left || 0) - this.padding,
				top: (this.iText.top || 0) - this.padding,
				width: ((this.iText as fabric.Textbox)?.width || 0) + this.padding * 2,
				height: ((this.iText as fabric.Textbox)?.height || 0) + this.padding * 2
			})
			this.resizeBtn.set({
				left: (this.iText.left || 0) + this.padding + ((this.iText as fabric.Textbox)?.width || 0) - 5,
				top: (this.iText.top || 0) - this.padding,
				height: ((this.iText as fabric.Textbox)?.height || 0) + this.padding * 2
			})
			this.iText.setCoords()
			this.rect.setCoords()
			this.canvas.requestRenderAll()
		}
	}
	_countTextWidth() {
		if(this.iText && this.rect) {
			const lineSize = this.iText?.textLines.length
			if(lineSize === 1) {
				if(!this.hasChangeWidth){
					this.iText.splitByGrapheme = false
					let width = this.iText.measureLine(0).width
					if(width >= this.autoMinWidth) {
						width = this.autoMinWidth
						this.iText.splitByGrapheme = true
					}
					this.iText.width = width
				}
			}
		}
	}
	setStyle(style: ItemStyle, isStatic: boolean = true) {
		const option:fabric.ITextboxOptions = {}
		const boxOption:fabric.IRectOptions = {}
		if(isStatic) {
			this.staticStyle = {...this.staticStyle, ...style}
			console.log(this.staticStyle)
		}
		if(style.color) {
			option.fill = this.staticStyle.color || style.color
		}
		if(style.backgroundColor) {
			boxOption.fill = this.staticStyle.backgroundColor || style.backgroundColor
		}
		if(style.padding) {
			this.padding = this.staticStyle.padding || style.padding
		}
		if(style.fontSize) {
			option.fontSize = this.staticStyle.fontSize || style.fontSize
		}
		if(style.lineHeight) {
			option.lineHeight = this.staticStyle.lineHeight || style.lineHeight
		}
		if(!this.staticStyle.textDecoration  && style.textDecoration === 'underline') {
			option.underline = true
		}
		if(!this.staticStyle.textDecoration  && style.textDecoration === 'line-through') {
			option.linethrough = true
		}
		if(!this.staticStyle.textDecoration  && style.textDecoration === 'none') {
			option.underline = false
			option.linethrough = false
		}
		if(style.textBackgroundColor) {
			option.textBackgroundColor = this.staticStyle.textBackgroundColor || style.textBackgroundColor
		}
		if(style.fontStyle) {
			option.fontStyle = this.staticStyle.fontStyle || style.fontStyle
		}
		this.iText.setOptions(option)
		this.rect.setOptions(boxOption)
		this.redrawBox()
	}
	setTextStyle(style: ItemTextStyle) {
		const option:fabric.ITextboxOptions = {}
		if(style.color) {
			option.fill = style.color
		}
		if(style.fontSize) {
			option.fontSize = style.fontSize
		}
		if(style.lineHeight) {
			option.lineHeight = style.lineHeight
		}
		if(style.textDecoration === 'underline') {
			option.underline = true
		}
		if(style.textDecoration === 'line-through') {
			option.linethrough = true
		}
		if(style.textDecoration === 'none') {
			option.underline = false
			option.linethrough = false
		}
		if(style.textBackgroundColor) {
			option.textBackgroundColor = style.textBackgroundColor
		}
		if(style.fontStyle) {
			option.fontStyle = style.fontStyle
		}
		this.iText.setSelectionStyles(option)
		this.redrawBox()
	}
	remove() {
		this.canvas.remove(this.iText)
		this.canvas.remove(this.rect)
	}
}